package com.eastfair.venuebooking.service.impl;

//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.auth.api.UserAccountServiceFeign;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.common.vo.AttachmentFileVO;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.exception.BizException;
import com.eastfair.pay.api.AttachmentFileFeign;
import com.eastfair.common.dto.AttachmentFileDTO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.venuebooking.dao.MaterialDeclarationMapper;
import com.eastfair.venuebooking.dto.*;
import com.eastfair.venuebooking.entity.ExhibitionMaterial;
import com.eastfair.venuebooking.entity.MaterialDeclaration;
import com.eastfair.venuebooking.enums.VenueBookingMoudleEnum;
import com.eastfair.venuebooking.exceptioncode.VenueBookingExceptionCode;
import com.eastfair.venuebooking.service.ExhibitionMaterialService;
import com.eastfair.venuebooking.service.MaterialDeclarationService;
import com.eastfair.venuebooking.vo.ExhibitionMaterialVO;
import com.eastfair.venuebooking.vo.MaterialDeclarationVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 材料申报
 * </p>
 *
 * @author linan
 * @date 2022-06-08
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class MaterialDeclarationServiceImpl extends SuperServiceImpl<MaterialDeclarationMapper, MaterialDeclaration> implements MaterialDeclarationService {

    @Resource
    private AttachmentFileFeign attachmentFileFeign;
    @Resource
    private ExhibitionMaterialService exhibitionMaterialService;
    @Resource
    private UserAccountServiceFeign userAccountServiceFeign;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<MaterialDeclaration> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(MaterialDeclaration model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        //雪花ID
        return R.successDef();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addMaterialDeclaration(MaterialDeclarationDTO materialDeclarationSaveDTO) {
        // 新增申报材料
        MaterialDeclaration materialDeclaration = new MaterialDeclaration();
        materialDeclaration.setMaterialNo(materialDeclarationSaveDTO.getMaterialNo());
        materialDeclaration.setMaterialName(materialDeclarationSaveDTO.getMaterialName());
        materialDeclaration.setAttamentUrl(materialDeclarationSaveDTO.getAttamentUrl());
        materialDeclaration.setProjectRemark(materialDeclarationSaveDTO.getProjectRemark());
        save(materialDeclaration);
        // 添加附件
        AttachmentFileDTO attachmentFile = materialDeclarationSaveDTO.getAttachmentFile();
        attachmentFile.setBusinessId(materialDeclaration.getId());
        attachmentFile.setBusinessType(VenueBookingMoudleEnum.MATERIAL_DECLARATION.getCode());
        attachmentFileFeign.addAttachmentFile(Collections.singletonList(attachmentFile));
        return materialDeclaration.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMaterialDeclaration(MaterialDeclarationDTO materialDeclarationUpdateDTO) {
        // 修改申报材料
        MaterialDeclaration updateEntity = new MaterialDeclaration();
        updateEntity.setId(materialDeclarationUpdateDTO.getId());
        updateEntity.setMaterialNo(materialDeclarationUpdateDTO.getMaterialNo());
        updateEntity.setMaterialName(materialDeclarationUpdateDTO.getMaterialName());
        updateEntity.setAttamentUrl(materialDeclarationUpdateDTO.getAttamentUrl());
        updateEntity.setProjectRemark(materialDeclarationUpdateDTO.getProjectRemark());
        // 修改附件
        AttachmentFileDTO attachmentFile = deleteOldFile(materialDeclarationUpdateDTO, updateEntity);
        attachmentFileFeign.addAttachmentFile(Collections.singletonList(attachmentFile));
        return updateById(updateEntity);
    }
    @Override
    public AttachmentFileDTO deleteOldFile(MaterialDeclarationDTO materialDeclarationUpdateDTO, MaterialDeclaration updateEntity) {
        AttachmentFileDTO attachmentFile = materialDeclarationUpdateDTO.getAttachmentFile();
        attachmentFile.setBusinessId(updateEntity.getId());
        attachmentFile.setBusinessType(VenueBookingMoudleEnum.MATERIAL_DECLARATION.getCode());
        R<List<AttachmentFileVO>> listR = attachmentFileFeign.queryAttachmentFile(attachmentFile);
        if(Objects.nonNull(listR) && CollectionUtils.isNotEmpty(listR.getData())){
            for (AttachmentFileVO datum : listR.getData()) {
                attachmentFileFeign.detele(datum.getId());
            }
        }
        return attachmentFile;
    }

    @Override
    public Long addExhibitionMaterial(ExhibitionMaterialSaveDTO exhibitionMaterialSaveDTO) {
        // 现场验收修改逻辑，新增覆盖之前的
        // 软删
        exhibitionMaterialService.update(new UpdateWrapper<ExhibitionMaterial>().lambda()
                .eq(ExhibitionMaterial::getExhibitionId,exhibitionMaterialSaveDTO.getExhibitionId())
                .set(ExhibitionMaterial::getIsDeleted,BusinessConstant.DELETE_YES));
        ExhibitionMaterial insertEntity = new ExhibitionMaterial();
        insertEntity.setExhibitionId(exhibitionMaterialSaveDTO.getExhibitionId());
        insertEntity.setMaterialId(exhibitionMaterialSaveDTO.getMaterialId());
        insertEntity.setAttamentUrl(exhibitionMaterialSaveDTO.getAttamentUrl());
        exhibitionMaterialService.save(insertEntity);
        // 添加附件
        if(Objects.nonNull(exhibitionMaterialSaveDTO.getAttachmentFileDTO())){
            AttachmentFileDTO attachmentFile = exhibitionMaterialSaveDTO.getAttachmentFileDTO();
            attachmentFile.setBusinessId(insertEntity.getId());
            attachmentFile.setBusinessType(VenueBookingMoudleEnum.EXHIBITION_MATERIAL.getCode());
            attachmentFileFeign.addAttachmentFile(Collections.singletonList(attachmentFile));
        }
        return insertEntity.getId();
    }

    @Override
    public IPage<MaterialDeclarationVO> queryMaterialDeclaration(PageParams<MaterialDeclarationQuery> params) {
        MaterialDeclarationQuery model = params.getModel();
        QueryWrapper<MaterialDeclaration> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(Objects.nonNull(model.getId()),MaterialDeclaration::getId,model.getId())
                .eq(MaterialDeclaration::getIsDeleted, BusinessConstant.NO)
                .like(StringUtils.isNotBlank(model.getMaterialName()),MaterialDeclaration::getMaterialName,model.getMaterialName())
                .ge(Objects.nonNull(model.getCreateTimeBegin()),MaterialDeclaration::getCreateTime,model.getCreateTimeBegin())
                .le(Objects.nonNull(model.getCreateTimeEnd()),MaterialDeclaration::getCreateTime,model.getCreateTimeEnd())
                .orderByDesc(SuperEntity::getCreateTime);
        Page<MaterialDeclaration> page = params.buildPage();
        page = this.page(page, queryWrapper);
        IPage<MaterialDeclarationVO> pageResult = params.buildPage();
        BeanUtils.copyProperties(page,pageResult);
        List<MaterialDeclaration> records = page.getRecords();
        List<MaterialDeclarationVO> materialDeclarationVOs = new ArrayList<>();
        for (MaterialDeclaration record : records) {
            try{
                MaterialDeclarationVO materialDeclarationVO = new MaterialDeclarationVO();
                BeanUtils.copyProperties(record,materialDeclarationVO);
                materialDeclarationVO.setId(record.getId());
                // 查询模版
                AttachmentFileDTO attachmentFileDTO = new AttachmentFileDTO();
                attachmentFileDTO.setBusinessId(record.getId());
                attachmentFileDTO.setBusinessType(VenueBookingMoudleEnum.MATERIAL_DECLARATION.getCode());
                R<List<AttachmentFileVO>> r = attachmentFileFeign.queryAttachmentFile(attachmentFileDTO);
                List<AttachmentFileVO> data = r.getData();
                if(CollectionUtils.isNotEmpty(data)){
                    materialDeclarationVO.setAttachmentFile(data.get(0));
                }
                materialDeclarationVOs.add(materialDeclarationVO);
            }catch (Exception e){
                log.error(VenueBookingExceptionCode.FILE_FOUND_ERROR.getMsg(),e);
                throw BizException.wrap(VenueBookingExceptionCode.FILE_FOUND_ERROR);
            }
        }
        pageResult.setRecords(materialDeclarationVOs);
        return pageResult;
    }

    @Override
    public List<ExhibitionMaterialVO> queryExhibitionMaterialByExhibitionId(Long exhibitionId, Long id) {
        QueryWrapper<ExhibitionMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ExhibitionMaterial::getIsDeleted, BusinessConstant.NO)
                .eq(ExhibitionMaterial::getExhibitionId, exhibitionId)
                .eq(Objects.nonNull(id),ExhibitionMaterial::getId, id)
                .orderByDesc(SuperEntity::getCreateTime);
        List<ExhibitionMaterial> list = exhibitionMaterialService.list(queryWrapper);
        List<ExhibitionMaterialVO> result = new ArrayList<>();
        // 一次性处理用户姓名
        Map<Long, String> userNames = new HashMap<>(8);
        if(CollectionUtils.isNotEmpty(list)){
            try{
                UserAccountDto userAccountDto = new UserAccountDto();
                userAccountDto.setUserIds(list.stream().map(SuperEntity::getCreatedBy).collect(Collectors.toList()));
                R<List<UserAccountVo>> listR = userAccountServiceFeign.querySimpleByIds(userAccountDto);
                if(CollectionUtils.isNotEmpty(listR.getData())){
                    listR.getData().forEach(e->userNames.put(e.getId(), e.getRealName()));
                }else {
                    log.warn("用户信息查询为空 {}",list.stream().map(SuperEntity::getCreatedBy).collect(Collectors.toList()));
                }
            }catch (Exception e){
                log.error("用户信息查询失败",e);
            }
        }
        for (ExhibitionMaterial exhibitionMaterial : list) {
            // 封装VO
            ExhibitionMaterialVO exhibitionMaterialVO = new ExhibitionMaterialVO();
            exhibitionMaterialVO.setId(exhibitionMaterial.getId());
            exhibitionMaterialVO.setExhibitionId(exhibitionId);
            exhibitionMaterialVO.setMaterialId(exhibitionMaterial.getMaterialId());
            exhibitionMaterialVO.setAttachmentUrl(exhibitionMaterial.getAttamentUrl());
            exhibitionMaterialVO.setCreateTime(exhibitionMaterial.getCreateTime());
            exhibitionMaterialVO.setCreateBy(exhibitionMaterial.getCreatedBy());
            exhibitionMaterialVO.setCreateByName(userNames.get(exhibitionMaterial.getCreatedBy()));
            // 查材料申请附件
            try{
                AttachmentFileDTO attachmentFileDTO = new AttachmentFileDTO();
                attachmentFileDTO.setBusinessId(exhibitionMaterial.getId());
                attachmentFileDTO.setBusinessType(VenueBookingMoudleEnum.EXHIBITION_MATERIAL.getCode());
                R<List<AttachmentFileVO>> r = attachmentFileFeign.queryAttachmentFile(attachmentFileDTO);
                List<AttachmentFileVO> data = r.getData();
                if(CollectionUtils.isNotEmpty(data)){
                    AttachmentFileVO attachmentFileVO = data.get(0);
                    exhibitionMaterialVO.setAttachmentFileVO(attachmentFileVO);
                    exhibitionMaterialVO.setAttachmentName(attachmentFileVO.getAttachmentName());
                    exhibitionMaterialVO.setAttachmentUrl(attachmentFileVO.getAttachmentUrl());
                    exhibitionMaterialVO.setAttachmentSize(attachmentFileVO.getAttachmentSize());
                    exhibitionMaterialVO.setAttachmentSubfix(attachmentFileVO.getAttachmentSubfix());
                }
            }catch (Exception e){
                log.error(VenueBookingExceptionCode.FILE_FOUND_ERROR.getMsg(),e);
                throw BizException.wrap(VenueBookingExceptionCode.FILE_FOUND_ERROR);
            }
            // 查材料申请明细
            MaterialDeclaration materialDeclaration = this.getById(exhibitionMaterial.getMaterialId());
            if(Objects.nonNull(materialDeclaration)){
                // 查询模版
                try{
                    MaterialDeclarationVO materialDeclarationVO = new MaterialDeclarationVO();
                    BeanUtils.copyProperties(materialDeclaration,materialDeclarationVO);
                    materialDeclarationVO.setId(materialDeclaration.getId());
                    AttachmentFileDTO attachmentFileDTO = new AttachmentFileDTO();
                    attachmentFileDTO.setBusinessId(materialDeclaration.getId());
                    attachmentFileDTO.setBusinessType(VenueBookingMoudleEnum.MATERIAL_DECLARATION.getCode());
                    R<List<AttachmentFileVO>> r = attachmentFileFeign.queryAttachmentFile(attachmentFileDTO);
                    List<AttachmentFileVO> data = r.getData();
                    if(CollectionUtils.isNotEmpty(data)){
                        materialDeclarationVO.setAttachmentFile(data.get(0));
                        exhibitionMaterialVO.setTemplateAttachmentUrl(data.get(0).getAttachmentUrl());
                    }
                    exhibitionMaterialVO.setMaterialName(materialDeclaration.getMaterialName());
                    exhibitionMaterialVO.setMaterialNo(materialDeclaration.getMaterialNo());
                    exhibitionMaterialVO.setMaterialDeclarationVO(materialDeclarationVO);
                }catch (Exception e){
                    log.error(VenueBookingExceptionCode.FILE_FOUND_ERROR.getMsg(),e);
                    throw BizException.wrap(VenueBookingExceptionCode.FILE_FOUND_ERROR);
                }
            }
            result.add(exhibitionMaterialVO);
        }
        return result;
    }
}
